# put patch: req 和模型定义的不匹配时，是怎么个行为？
# 转变思路：写了模型用了 ORM 之后，都是对模型的操作，而不是直接写 SQL

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str | None = None
    description: str | None = None
    price: float | None = None
    tax: float = 10.5
    tags: list[str] = []


items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}


@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
    # 查询foo 没有的字段 按模型补全 返回 {"name": "Foo","description": null,"price": 50.2,"tax": 10.5,"tags": []}
    return items[item_id]

# 部分更新
@app.patch("/items/{item_id}", response_model=Item)
async def update_item(item_id: str, item: Item):
    stored_item_data = items[item_id]
    stored_item_model = Item(**stored_item_data) # 获取存储的项数据
    update_data = item.model_dump(exclude_unset=True) # 将 item 转换为字典形式，提取出要更新的数据。只更新 req 里有的字段。需要模型所有字段都标记为可选或使用默认值
    updated_item = stored_item_model.model_copy(update=update_data) # 创建 stored_item_model 的一个副本，并用 update_data 中的数据更新该副本。
    items[item_id] = jsonable_encoder(updated_item) # 将更新后的项以 JSON 可编码的格式存回 items 字典中。
    return updated_item

# 全更新
@app.put("/items2/{item_id}", response_model=Item)
async def update_item2(item_id: str, item: Item):
    update_item_encoded = jsonable_encoder(item)
    items[item_id] = update_item_encoded
    return update_item_encoded